/*******************************************************************************
 *
 *	ViP model for FIMGSE
 *		version 1.0
 *
 *	MultiTex.c
 *
 *	by cheolkyoo.kim
 *	Graphics IP Team in AP, Mobile Solution Development,
 *	System LSI Division, Semiconductor Business,
 *	Samsung Electronics
 *
 *	Copyright (c) 2005 FIMG team
 *
 *	All rights reserved. No part of this program may be reproduced, stored
 *	in a retrieval system, or tranmitted, in any form or by any means,
 *	electronic, mechanical, photocopying, recording, or otherwise, without
 *	the prior written permission of the author.
 *
 *	2008. 5. 19  by cheolkyoo.kim
 *
 *  Description
 *
 ******************************************************************************/
/****************************************************************************
 *  INCLUDES
 ****************************************************************************/
#include "library.h"
#include "defines.h"

#include "fgl.h"
#include "Config.h"
#include "Fimg3DTest.h"
#include "SysUtility.h"
#include "Matrix4.h"

#include "intc.h"
#include "lcd.h"

#include "Earth.vsa.h"
#include "Earth.psa.h"


static struct texture_info s_stTextureInfo[3] = {
    {
    	TEX_2D, 
    	CKEY0, 
    	false, 
    	false,
    	PAL_ARGB8888,
    	TFMT_ARGB8888,
    	TWM_REPEAT,
    	TWM_REPEAT,
    	TWM_REPEAT,
    	false,
    	true,
    	true,
    	TFLR_NONE,
    	
    	1024,
    	512,
    	1,
    	(FIMG_TEXTURE_MEMORY + 0x80)
    },
    
    {
    	TEX_2D, 
    	CKEY0, 
    	false, 
    	false,
    	PAL_ARGB8888,
    	TFMT_ARGB8888,
    	TWM_REPEAT,
    	TWM_REPEAT,
    	TWM_REPEAT,
    	false,
    	true,
    	true,
    	TFLR_NONE,
    	
    	1024,
    	512,
    	1,
    	(FIMG_TEXTURE_MEMORY + 0x200080 + 0x80)
    },
    
    {
    	TEX_2D, 
    	CKEY0, 
    	false, 
    	false,
    	PAL_ARGB8888,
    	TFMT_ARGB8888,
    	TWM_REPEAT,
    	TWM_REPEAT,
    	TWM_REPEAT,
    	false,
    	true,
    	true,
    	TFLR_NONE,
    	
    	1024,
    	512,
    	1,
    	(FIMG_TEXTURE_MEMORY + 0x400100 + 0x80)
    }
};

static struct vertex_context        s_stVertexInfo   = { TRIANGLE_STRIP, 3, 0, false };
static struct host_interface_info   s_stHostIFInfo   = { IDT_UINT, 4, false, true, false };
static struct attribute_info        s_stAttribInfo[3] = 
{
    { FIRST, SECOND, THIRD, FOURTH, 3, ADT_FLOAT, false },
    { FIRST, SECOND, THIRD, FOURTH, 3, ADT_FLOAT, false },
    { FIRST, SECOND, THIRD, FOURTH, 2, ADT_FLOAT, true }
};

static volatile bool s_b3DIntOccured;
static volatile u32  s_uSwapBuffer;

void __irq Isr_Fimg3D(void)
{
	fgl_disable_int();
	fgl_clear_pending_int();
	
	s_b3DIntOccured = true;

	if ( s_uSwapBuffer < 2)
		s_uSwapBuffer++;
	else 
		s_uSwapBuffer = 0;

	INTC_ClearVectAddr();
}


void TestEarth(void)
{

	float aspect = 800.f / 480.f;
	float vp     = 0.8f;
	float zoom   = 0.8f;
	float left   = -vp;
	float right  =  vp;
	float bottom = -vp / aspect;
	float top    =  vp / aspect;
	float znear  = 2.f;
	float zfar   = 1000.f;

   	int          nLoop          = 50;
	float        fRot           = 0.0f;
   	unsigned int nNumOfVertices = 1680;
   	unsigned int nNumOfData     = 1680 * 8;
	unsigned int uiDummy        = 0xFFFFFFFF;
	
	s_uSwapBuffer   = 2;
	s_b3DIntOccured = false;

	Matrix4 ModelViewProjectionMatrix, ModelViewMatrix, ProjectionMatrix;
	Matrix4 TransposeModelViewMatrix, InverseModelViewMatrix;

	ProjectionMatrix.SetAsFrustumMatrix(left * zoom, right * zoom, bottom * zoom, top * zoom, znear, zfar);
	
	drvsys_clear_buf((unsigned int *)FIMG_DEPTH_BUFFER, CLEAR_SCREEN_SIZE, 0xFFFFFFFF);
	drvsys_clear_buf((unsigned int *)FIMG_COLOR_BUFFER, CLEAR_SCREEN_SIZE, 0x0);
	
	fgl_pipeline_isempty(PSF_ALL);	// Pipeline status
    
	fgl_load_vs(Earth_vsa);
	fgl_load_fs(Earth_psa);

	
 	float LightPosition[4] = { 3.f, 3.f, 0.f, 0.f};
 	fglWriteVertexShaderConstFloat(44, 4, LightPosition);
 	
	INTC_SetVectAddr(NUM_3D, Isr_Fimg3D);
	INTC_Enable(NUM_3D);

	fgl_interrupt_mask(PSF_ALL);
	fgl_interrupt_target(0); 	

	fgl_vs_inattrib(3);
	fgl_fs_inattrib(3);
    
	fgl_cull_face(false, BACKFACE);

	fgl_depthbuf_base(FIMG_DEPTH_BUFFER);
	fgl_depth(CF_LESS);

	fgl_texture( 0, (void *)&s_stTextureInfo[0] );
	fgl_texture( 1, (void *)&s_stTextureInfo[1] );
	fgl_texture( 2, (void *)&s_stTextureInfo[2] );
	
	fgl_vertex         ( &s_stVertexInfo );
	fgl_host_interface ( &s_stHostIFInfo );
	fgl_attribute      ( 3, &s_stAttribInfo );
	
   	drvsys_clear_buf((unsigned int *)FIMG_DEPTH_BUFFER, CLEAR_SCREEN_SIZE, 0xFFFFFFFF);
   	drvsys_clear_buf((unsigned int *)FIMG_COLOR_BUFFER, CLEAR_SCREEN_SIZE, 0x0);

	do
	{
		
        ModelViewMatrix.LoadIdentity();
     	// Thomas, Kim
     	ModelViewMatrix.Rotate(0.0f, 1.0f, 0.0f, fRot);
     	ModelViewMatrix.Translate(0.f, 0.f, -7.5f);
     	TransposeModelViewMatrix = ModelViewMatrix.Transpose();
     	fglWriteVertexShaderConstFloat(0, 16, TransposeModelViewMatrix.m[0]);
     	InverseModelViewMatrix = ModelViewMatrix.Inverse();
     	fglWriteVertexShaderConstFloat(16, 11, InverseModelViewMatrix.m[0]);
     	ModelViewProjectionMatrix = ProjectionMatrix * ModelViewMatrix;
     	fglWriteVertexShaderConstFloat(28, 16, ModelViewProjectionMatrix.m[0]);
 	
		fgl_transfer_fifo ( &nNumOfVertices, 4 );
		fgl_transfer_fifo ( &uiDummy, 4 );
		
		//fglDumpContext("dump.txt");
		
		fglSysTransferToPort ( (unsigned int *)FIMG_GEOMETRY_MEMORY, nNumOfData );

		//fgl_pipeline_isempty( PSF_ALL );	// Pipeline status
       	fgl_flush_cache     ( CF_ALL  );
		fgl_enable_int();
		
		while(!s_b3DIntOccured);
		
		if(s_uSwapBuffer == 0) 
		{
			LCD_InitWin(RGB24, 800, 480, 0, 0, 800, 480, 0, 0, FIMG_COLOR_BUFFER_0, WIN0, false);

			drvsys_clear_buf((unsigned int*)FIMG_DEPTH_BUFFER, CLEAR_SCREEN_SIZE, 0xFFFFFFFF);
			drvsys_clear_buf((unsigned int*)(FIMG_COLOR_BUFFER_1), CLEAR_SCREEN_SIZE, 0xFF000000);
			fgl_colorbuf_base(FIMG_COLOR_BUFFER_1);
		}
		else if(s_uSwapBuffer == 1)
		{
			LCD_InitWin(RGB24, 800, 480, 0, 0, 800, 480, 0, 0, FIMG_COLOR_BUFFER_1, WIN0, false);
			
	        drvsys_clear_buf((unsigned int*)FIMG_DEPTH_BUFFER, CLEAR_SCREEN_SIZE, 0xFFFFFFFF);
			drvsys_clear_buf((unsigned int*)(FIMG_COLOR_BUFFER_2), CLEAR_SCREEN_SIZE, 0xFF000000);
			fgl_colorbuf_base(FIMG_COLOR_BUFFER_2);
		} 
		else if(s_uSwapBuffer == 2) 
		{
			LCD_InitWin(RGB24, 800, 480, 0, 0, 800, 480, 0, 0, FIMG_COLOR_BUFFER_2, WIN0, false);

			drvsys_clear_buf((unsigned int*)FIMG_DEPTH_BUFFER, CLEAR_SCREEN_SIZE, 0xFFFFFFFF);
			drvsys_clear_buf((unsigned int*)(FIMG_COLOR_BUFFER_0), CLEAR_SCREEN_SIZE, 0xFF000000);
			fgl_colorbuf_base(FIMG_COLOR_BUFFER_0);
		}
		else
		{
			UART_Printf("nbuffer = %d\n", s_uSwapBuffer);
			while(!s_b3DIntOccured);			
			//Assert(0);
		}

    	fRot += 2.0f;
    	if( fRot > 359.0f ) fRot = 2.0f;
    	
    	UART_Printf("frame %d\n", nLoop);

    } while(--nLoop != 0); 
       
    fgl_disable_depth();
    fgl_disable_cullface();

}

